package net.googlecode.demenkov.task3;

import java.math.BigDecimal;

/**
 * Calculator to count employees salary.
 *
 * @author Yura Demenkov
 */
public class SalaryCalculator {
    private BigDecimal mngTax;
    private BigDecimal empTax;
    private BigDecimal bossTax;

    /**
     * Constructor, creates salary calculator with default taxes.
     */
    public SalaryCalculator() {
        this.setBossTax(new BigDecimal(500));
        this.setManagerTax(new BigDecimal(250));
        this.setEmployeeTax(new BigDecimal(125));
    }

    /**
     * Constructor that creates salary calculator with entered taxes.
     *
     * @param bossTax Boss tax
     * @param mngTax  Manager tax
     * @param empTax  Employee tax
     */
    public SalaryCalculator(final BigDecimal bossTax, final BigDecimal mngTax, final BigDecimal empTax) {
        this.setBossTax(bossTax);
        this.setManagerTax(mngTax);
        this.setEmployeeTax(empTax);
    }

    /**
     * Counts Manager's salary.
     *
     * @param m Manager.
     * @return manager's salary.
     */
    private BigDecimal countSalary(final Manager m) {
        BigDecimal salary = new BigDecimal(0);
        if (m.isPerHour()) {
            salary = new BigDecimal(170).multiply(m.getRate());
        } else {
            salary = m.getRate();
        }

        if (m.isBonus()) {
            salary = salary.add(m.getBonusAmount());
        }
        salary = salary.subtract(mngTax);
        return salary;
    }

    /**
     * Counts Employee's salary.
     *
     * @param e Employee
     * @return Employee's salary
     */
    private BigDecimal countSalary(final Employee e) {
        BigDecimal salary = new BigDecimal(0);
        if (e.isPerHour()) {
            //170 hours in month
            salary = new BigDecimal(170).multiply(e.getRate());
        } else {
            //salary = rate * experience
            salary = e.getRate().multiply(new BigDecimal(e.getExperience()));
        }

        if (e.isBonus()) {
            salary = salary.add(e.getBonusAmount());
        }
        salary = salary.subtract(empTax);
        return salary;
    }

    /**
     * Counts Boss salary.
     *
     * @param b Boss
     * @return Boss salary
     */
    private BigDecimal countSalary(final Boss b) {
        BigDecimal salary = new BigDecimal(170).multiply(b.getRate());
        salary = salary.add(b.getBonusAmount());
        salary = salary.subtract(bossTax);
        return salary;
    }

    /**
     * Prints personal information about person: Profession, name, age, salary.
     *
     * @param person Person
     */
    private void printPersonalInfo(final PersonalInfo person, BigDecimal salary) {
        System.out.println(person.getClass().getSimpleName() + " >> " + person.getName() + ", age: " + person.getAge() + ", salary: $" + salary);
    }

    /**
     * Sets Employees tax
     *
     * @param empTax employees tax
     */
    public void setEmployeeTax(final BigDecimal empTax) {
        this.empTax = empTax;
    }

    /**
     * Sets managers tax
     *
     * @param mngTax managers tax
     */
    public void setManagerTax(final BigDecimal mngTax) {
        this.mngTax = mngTax;
    }

    /**
     * Sets boss tax
     *
     * @param bossTax boss tax
     */
    public void setBossTax(final BigDecimal bossTax) {
        this.bossTax = bossTax;
    }

    /**
     * Checks who is the person and counts person's salary.
     *
     * @param person
     */
    public void calcSalary(PersonalInfo person) {
        BigDecimal salary = new BigDecimal(0);

        if (person instanceof Manager) {
            printPersonalInfo((Manager) person, countSalary((Manager) person));
        } else if (person instanceof Employee) {
            printPersonalInfo((Employee) person, countSalary((Employee) person));
        } else {
            if (person instanceof Boss) {
                printPersonalInfo((Boss) person, countSalary((Boss) person));
            }
        }


    }
}
